﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;

namespace GMap.NET.WindowsForms
{

    /// <summary>
    /// GMap.NET marker
    /// </summary>
    [Serializable]
    public class GMapToolTip : ISerializable, IDisposable
    {
        GMapMarker marker;
        public GMapMarker Marker
        {
            get
            {
                return marker;
            }
            internal set
            {
                marker = value;
            }
        }

        public Point Offset;

        public static readonly StringFormat DefaultFormat = new StringFormat();

        /// <summary>
        /// string format
        /// </summary>
        [NonSerialized]
        public readonly StringFormat Format = DefaultFormat;

        public static readonly Font DefaultFont = new Font(FontFamily.GenericSansSerif, 14, FontStyle.Bold, GraphicsUnit.Pixel);

        /// <summary>
        /// font
        /// </summary>
        [NonSerialized]
        public Font Font = DefaultFont;

        public static readonly Pen DefaultStroke = new Pen(Color.FromArgb(140, Color.MidnightBlue));

        /// <summary>
        /// specifies how the outline is painted
        /// </summary>
        [NonSerialized]
        public Pen Stroke = DefaultStroke;

        public static readonly Brush DefaultFill = new SolidBrush(Color.FromArgb(222, Color.AliceBlue));

        /// <summary>
        /// background color
        /// </summary>
        [NonSerialized]
        public Brush Fill = DefaultFill;

        public static readonly Brush DefaultForeground = new SolidBrush(Color.Navy);

        /// <summary>
        /// text foreground
        /// </summary>
        [NonSerialized]
        public Brush Foreground = DefaultForeground;

        /// <summary>
        /// text padding
        /// </summary>
        public Size TextPadding = new Size(10, 10);

        static GMapToolTip()
        {
            DefaultStroke.Width = 2;
            DefaultStroke.LineJoin = LineJoin.Round;
            DefaultStroke.StartCap = LineCap.RoundAnchor;

            DefaultFormat.LineAlignment = StringAlignment.Near;
            DefaultFormat.Alignment = StringAlignment.Near;
        }

        public GMapToolTip(GMapMarker marker)
        {
            this.Marker = marker;
            this.Offset = new Point(14, -44);
        }

        public virtual void OnRender(Graphics g)
        {
            System.Drawing.Size st = g.MeasureString(Marker.ToolTipText, Font).ToSize();
            System.Drawing.Rectangle rect = new System.Drawing.Rectangle(Marker.ToolTipPosition.X, Marker.ToolTipPosition.Y - st.Height, st.Width + TextPadding.Width, st.Height + TextPadding.Height);
            rect.Offset(Offset.X, Offset.Y);

            g.DrawLine(Stroke, Marker.ToolTipPosition.X, Marker.ToolTipPosition.Y, rect.X, rect.Y + rect.Height / 2);

            g.FillRectangle(Fill, rect);
            g.DrawRectangle(Stroke, rect);

            g.DrawString(Marker.ToolTipText, Font, Foreground, rect, Format);
        }

        #region ISerializable Members

        /// <summary>
        /// Initializes a new instance of the <see cref="GMapToolTip"/> class.
        /// </summary>
        /// <param name="info">The info.</param>
        /// <param name="context">The context.</param>
        protected GMapToolTip(SerializationInfo info, StreamingContext context)
        {
            this.Offset = Extensions.GetStruct<Point>(info, "Offset", Point.Empty);
            this.TextPadding = Extensions.GetStruct<Size>(info, "TextPadding", new Size(10, 10));
        }

        /// <summary>
        /// Populates a <see cref="T:System.Runtime.Serialization.SerializationInfo"/> with the data needed to serialize the target object.
        /// </summary>
        /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"/> to populate with data.</param>
        /// <param name="context">The destination (see <see cref="T:System.Runtime.Serialization.StreamingContext"/>) for this serialization.</param>
        /// <exception cref="T:System.Security.SecurityException">
        /// The caller does not have the required permission.
        /// </exception>
        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Offset", this.Offset);
            info.AddValue("TextPadding", this.TextPadding);
        }

        #endregion

        #region IDisposable Members

        bool disposed = false;

        public void Dispose()
        {
            if (!disposed)
            {
                disposed = true;
            }
        }

        #endregion
    }
}
